package com.ruoyi.web.controller.pay;

import cn.hutool.extra.qrcode.QrCodeUtil;
import com.github.binarywang.wxpay.bean.notify.WxPayOrderNotifyResult;
import com.github.binarywang.wxpay.bean.request.WxPayUnifiedOrderRequest;
import com.github.binarywang.wxpay.bean.result.WxPayOrderQueryResult;
import com.github.binarywang.wxpay.bean.result.WxPayUnifiedOrderResult;
import com.github.binarywang.wxpay.constant.WxPayConstants;
import com.github.binarywang.wxpay.exception.WxPayException;
import com.github.binarywang.wxpay.service.WxPayService;
import com.github.binarywang.wxpay.util.SignUtils;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.core.domain.entity.SysUser;
import com.ruoyi.common.enums.OrderState;
import com.ruoyi.common.utils.SecurityUtils;
import com.ruoyi.common.utils.bean.BeanUtils;
import com.ruoyi.system.domain.BizPayOrder;
import com.ruoyi.system.domain.BizPayQrcode;
import com.ruoyi.system.service.IBizPayOrderService;
import com.ruoyi.system.service.IBizPayQrcodeService;
import com.ruoyi.web.entity.vo.CreateOrderVo;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.imageio.ImageIO;
import javax.servlet.http.HttpServletRequest;
import java.awt.image.BufferedImage;
import java.io.ByteArrayOutputStream;
import java.math.BigDecimal;
import java.util.Base64;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 微信Native支付接口
 * @author wjz
 * @date 2021/5/28
 */
@Api("支付模块接口")
@RequestMapping("/pay")
@RestController
public class PayController {

    @Autowired
    IBizPayQrcodeService qrcodeService;
    @Autowired
    IBizPayOrderService orderService;
    @Autowired
    WxPayService wxPayService;

    /**
     * 创建QRcode支付二维码
     */
    @ApiOperation("创建QRcode支付二维码")
    @GetMapping("/payment/qrcode/{storeId}/{appId}")
    public AjaxResult getQrCode(@PathVariable("storeId")Long storeId, @PathVariable("appId")Long appId, HttpServletRequest request){
        final HashMap<String, String> stringStringHashMap = new HashMap<>();
        final BizPayQrcode bizPayQrcode = new BizPayQrcode();
        bizPayQrcode.setAppId(appId);
        bizPayQrcode.setStoreId(storeId);
        bizPayQrcode.setCreateBy(SecurityUtils.getUsername());
        final List<BizPayQrcode> bizPayQrcodes = qrcodeService.selectBizPayQrcodeList(bizPayQrcode);
        if(bizPayQrcodes != null && bizPayQrcodes.size() != 0){
            stringStringHashMap.put("base64",bizPayQrcodes.get(0).getBase64());
            return AjaxResult.success("创建成功",stringStringHashMap);
        }
        //用户扫码后，前端提供的支付路由：http://pay.hhzzss.cn/payment?storeId=xx&appId=xx
        String paymentRoute = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+"/payment?storeId="+storeId+"&appId="+appId;
        final BufferedImage generate = QrCodeUtil.generate(paymentRoute, 80, 80);
        final ByteArrayOutputStream outStream = new ByteArrayOutputStream();
        try {
            ImageIO.write(generate,"png",outStream);
        }catch (Exception e){
            e.printStackTrace();
        }
        bizPayQrcode.setBase64(Base64.getEncoder().encodeToString(outStream.toByteArray()));
        qrcodeService.insertBizPayQrcode(bizPayQrcode);
        stringStringHashMap.put("base64",bizPayQrcode.getBase64());
        return AjaxResult.success("创建成功",stringStringHashMap);
    }

    /**
     * 通过前端提供的路由点击支付后，创建新的订单  并 拉起native支付
     */
    @ApiOperation("创建微信订单")
    @PostMapping("/payment/createOrder")
    public AjaxResult createOrder(@RequestBody CreateOrderVo orderVo) throws WxPayException {
        final BizPayOrder bizPayOrder = new BizPayOrder();
        BeanUtils.copyBeanProp(orderVo,bizPayOrder);
//        final SysUser user = SecurityUtils.getLoginUser().getUser();
        bizPayOrder.setStoreId(orderVo.getStoreId());
        bizPayOrder.setAppId(orderVo.getAppId());
        bizPayOrder.setMoney(new BigDecimal(orderVo.getMoney()));
//        bizPayOrder.setUserId(user.getUserId());
        bizPayOrder.setCreateBy("系统创建");
        bizPayOrder.setState(OrderState.NOT_PAID.getCode());
        orderService.insertBizPayOrder(bizPayOrder);

        //拉起微信navtive支付订单
        //orderId, orderAmount, orderType
        final WxPayUnifiedOrderRequest wxPayUnifiedOrderRequest = new WxPayUnifiedOrderRequest();
        wxPayUnifiedOrderRequest.setTradeType(WxPayConstants.TradeType.NATIVE);
        //订单金额乘以100传递
        wxPayUnifiedOrderRequest.setTotalFee(bizPayOrder.getMoney().multiply(new BigDecimal("100")).intValue());
        wxPayUnifiedOrderRequest.setOutTradeNo(bizPayOrder.getOrderId()+"");
        wxPayUnifiedOrderRequest.setBody("一个测试订单");
        final HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
        wxPayUnifiedOrderRequest.setSpbillCreateIp(request.getRemoteHost());
        String notifyUrl = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+"/payment/notify/order";
        wxPayUnifiedOrderRequest.setNotifyUrl(notifyUrl);
        wxPayUnifiedOrderRequest.setProductId("juhepay_productId_"+bizPayOrder.getOrderId());
        final HashMap<String, String> argsMap = new HashMap<>();
        argsMap.put("tarde_type",wxPayUnifiedOrderRequest.getTradeType());
        argsMap.put("total_fee",wxPayUnifiedOrderRequest.getTotalFee()+"");
        argsMap.put("out_trade_no",wxPayUnifiedOrderRequest.getOutTradeNo());
        argsMap.put("body",wxPayUnifiedOrderRequest.getBody());
        argsMap.put("spbill_create_ip",wxPayUnifiedOrderRequest.getSpbillCreateIp());
        argsMap.put("notify_url",wxPayUnifiedOrderRequest.getNotifyUrl());
        argsMap.put("product_id",wxPayUnifiedOrderRequest.getProductId());
        final String sign = SignUtils.createSign(argsMap, WxPayConstants.SignType.MD5, "guatDevelopersguatDevelopers1234", null);
        wxPayUnifiedOrderRequest.setSign(sign);
        final WxPayUnifiedOrderResult wxPayUnifiedOrderResult = wxPayService.unifiedOrder(wxPayUnifiedOrderRequest);
        Map map = new HashMap<>();
        map.put("codeUrl",wxPayUnifiedOrderResult.getCodeURL());
        map.put("orderId",wxPayUnifiedOrderResult.getPrepayId());
        map.put("thisSystemOrderId",bizPayOrder.getOrderId());
        return AjaxResult.success("创建成功",map);
    }


    @ApiOperation("查询订单")
    @GetMapping("/payment/{orderId}")
    public AjaxResult queryByOrderId(@PathVariable("orderId")String orderId) throws WxPayException {
        final WxPayOrderQueryResult wxPayOrderQueryResult = wxPayService.queryOrder(null, orderId);
        final String tradeState = wxPayOrderQueryResult.getTradeState();
        if(WxPayConstants.WxpayTradeStatus.SUCCESS.equalsIgnoreCase(tradeState)){
            //更新订单db状态
            final BizPayOrder bizPayOrder = new BizPayOrder();
            bizPayOrder.setOrderId(Long.parseLong(wxPayOrderQueryResult.getOutTradeNo()));
            bizPayOrder.setState(OrderState.PAID.getCode());
            orderService.updateBizPayOrder(bizPayOrder);
            return AjaxResult.success("成功支付");
        }
        return  AjaxResult.error("未成功支付,订单状态："+tradeState);
    }

    @ApiOperation("支付回调")
    @PostMapping("/payment/notify/order")
    public AjaxResult parseOrderNotifyXml(@RequestBody String xmlData) throws WxPayException {
        final WxPayOrderNotifyResult wxPayOrderNotifyResult = wxPayService.parseOrderNotifyResult(xmlData);
        final String outTradeNo = wxPayOrderNotifyResult.getOutTradeNo();
        if(WxPayConstants.ResultCode.SUCCESS.equalsIgnoreCase(wxPayOrderNotifyResult.getResultCode())){
            //更新订单db状态
            final BizPayOrder bizPayOrder = new BizPayOrder();
            bizPayOrder.setOrderId(Long.parseLong(wxPayOrderNotifyResult.getOutTradeNo()));
            bizPayOrder.setState(OrderState.PAID.getCode());
            orderService.updateBizPayOrder(bizPayOrder);
            return AjaxResult.success("成功支付");
        }
        return AjaxResult.error("未成功支付，回调处理结束");
    }


    public static void main(String[] args) {
        //用户扫码后，前端提供的支付路由：http://pay.hhzzss.cn/payment?storeId=xx&appId=xx
        String paymentRoute = "http://main.shanjupay.hhzzss.cn/payment?storeId=1&appId=1";
        final BufferedImage generate = QrCodeUtil.generate(paymentRoute, 80, 80);
        final ByteArrayOutputStream outStream = new ByteArrayOutputStream();
        try {
            ImageIO.write(generate,"png",outStream);
        }catch (Exception e){
            e.printStackTrace();
        }
        System.out.println(Base64.getEncoder().encodeToString(outStream.toByteArray()));
    }
}



